Segal
Files:for i in range(10000):
output = model(input_tensor)
loss = lossfunc(output, target_output)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if torch.allclose(target_output, output, rtol=1e-10, atol=1e-10):
break
print("Input:", tensor_to_ascii(input_tensor), "Loss: ", loss.item()) rn i get it going to loss of inf (edited)for i in range(10000):
output = model(input_tensor)
loss = lossfunc(output, target_output)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if torch.allclose(target_output, output, rtol=1e-10, atol=1e-10):
break
print("Input:", tensor_to_ascii(input_tensor), "Loss: ", loss.item()) rn i get it going to loss of inf (edited)y=Wx+b and y W b are all knownnn.Linear(13, 37)
we have y = W * x + b
where
b is size 37x1
W is size 37x13
y is size 37x1 (the output)
we need to recover x which is 13x1def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(int(x.item()))
except:
data += "\x00"
return data (edited)def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(int(x.item()))
except:
data += "\x00"
return data (edited)output = open("model (1).txt").read()
outputs = open("outputs (2).txt").read()
data = output.split("layer")
import torch
import numpy as np
def rm_empty(l):
if '' in l:
l.remove('')
return l
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(int(x.item()))
except:
data += "\x00"
return data
data = rm_empty(data)
from torch import tensor
def parse_data(d):
dn = rm_empty(d.split("\n"))
lr = dn[0]
d2 = ("\n".join(dn[1:])).split("weights")
d2 = rm_empty(d2)
biases = d2[0]
biases = rm_empty(biases.split("\n"))[1:][0]
biases = tensor(eval('[np.float64(' + biases.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64)
weights = rm_empty(d2[1].split("\n"))
for i in range(len(weights)):
weights[i] = eval('[np.float64(' + weights[i].replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]')
return lr, biases, tensor(weights, dtype=torch.float64)
weights = []
biases = []
for x in range(len(data)):
_, lrbiases, lrweights = parse_data(data[x])
weights.append(lrweights)
biases.append(lrbiases)
from torch import nn
model = nn.Sequential(
nn.Linear(22, 69),
nn.Linear(69, 420),
nn.Linear(420, 800),
nn.Linear(800, 85),
nn.Linear(85, 13),
nn.Linear(13, 37)
)
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(round(x.item()))
except:
data += "\x00"
return data
for i, layer in enumerate(model):
if isinstance(layer, nn.Linear):
layer.weight = nn.Parameter(weights[i])
layer.biases = nn.Parameter(biases[i])
target_output = tensor(eval('[np.float64(' + outputs.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64) (edited)prefix = "UMDCTF{"
suffix = "}"
input_tensor = torch.zeros(22, dtype=torch.float64)
for i in range(len(prefix)):
input_tensor[i] = ord(prefix[i])
input_tensor[-1] = ord(suffix)
for i in range(len(prefix), len(input_tensor) - 1):
input_tensor[i] = torch.randint(low=32, high=127, size=(1,), dtype=torch.float64)
input_tensor.requires_grad = True
MSE = nn.MSELoss()
from torch.optim import *
for x in range(0,10):
optimizer = RMSprop([input_tensor], lr=0.1**x)
for i in range(1000):
print(loss)
output = model(input_tensor)
loss = MSE(output, target_output)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if torch.allclose(output, target_output, rtol=1e-10, atol=1e-10):
break
print(tensor_to_ascii(input_tensor)) (edited)output = open("model (1).txt").read()
outputs = open("outputs (2).txt").read()
def rm_empty(l):
if '' in l:
l.remove('')
return l
from fractions import Fraction
def parse_data(d):
dn = rm_empty(d.split("\n"))
lr = dn[0]
d2 = ("\n".join(dn[1:])).split("weights")
d2 = rm_empty(d2)
biases = d2[0]
biases = rm_empty(biases.split("\n"))[1:][0]
biases = eval('[Fraction("' + biases.replace(" ", '"), Fraction("') + '")]')
weights = rm_empty(d2[1].split("\n"))
for i in range(len(weights)):
weights[i] = eval('[Fraction("' + weights[i].replace(" ", '"), Fraction("') + '")]')
return lr, biases, weights
weights = []
biases = []
for x in range(len(data)):
_, lrbiases, lrweights = parse_data(data[x])
weights.append(lrweights)
biases.append(lrbiases)
target_output = eval('[Fraction("' + outputs.replace(" ", '"), Fraction("') + '")]')8518196211434573697728037/100000000000000000 as string[y1 ... y37] = [37x13] * [x1 ... x13]
need to solve for x given yFraction could achieve it imo)
also we can multiply everything by 1000 before calculation then divide by 1000prefix = "UMDCTF{"
suffix = "}"
input_tensor = torch.zeros(22, dtype=torch.float64)
for i in range(len(prefix)):
input_tensor[i] = ord(prefix[i])
input_tensor[-1] = ord(suffix)
for i in range(len(prefix), len(input_tensor) - 1):
input_tensor[i] = torch.randint(low=32, high=127, size=(1,), dtype=torch.float64)
input_tensor.requires_grad = True
MSE = nn.MSELoss()
from torch.optim import *
for x in range(0,10):
optimizer = RMSprop([input_tensor], lr=0.1**x)
for i in range(1000):
print(loss)
output = model(input_tensor)
loss = MSE(output, target_output)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if torch.allclose(output, target_output, rtol=1e-10, atol=1e-10):
break
print(tensor_to_ascii(input_tensor)) (edited)tensor([ 74.8768, 91.2488, 30.9799, -82.4857, -79.5941, 50.4259, 92.7775,
33.6500, -21.4305, 94.0301, 84.4334, 91.1794, 54.6718, 28.5342,
31.8013, 12.2619, 25.8559, -42.9601, 88.9332, 28.9249, 82.2870,
33.0996], dtype=torch.float64, requires_grad=True) my tensor btwoutput = open("model (1).txt").read()
outputs = open("outputs (2).txt").read()
data = output.split("layer")
import torch
import numpy as np
def rm_empty(l):
if '' in l:
l.remove('')
return l
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(int(x.item()))
except:
data += "\x00"
return data
data = rm_empty(data)
from torch import tensor
def parse_data(d):
dn = rm_empty(d.split("\n"))
lr = dn[0]
d2 = ("\n".join(dn[1:])).split("weights")
d2 = rm_empty(d2)
biases = d2[0]
biases = rm_empty(biases.split("\n"))[1:][0]
biases = tensor(eval('[np.float64(' + biases.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64)
weights = rm_empty(d2[1].split("\n"))
for i in range(len(weights)):
weights[i] = eval('[np.float64(' + weights[i].replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]')
return lr, biases, tensor(weights, dtype=torch.float64)
weights = []
biases = []
for x in range(len(data)):
_, lrbiases, lrweights = parse_data(data[x])
weights.append(lrweights)
biases.append(lrbiases)
from torch import nn
model = nn.Sequential(
nn.Linear(22, 69),
nn.Linear(69, 420),
nn.Linear(420, 800),
nn.Linear(800, 85),
nn.Linear(85, 13),
nn.Linear(13, 37)
)
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(round(x.item()))
except:
data += "\x00"
return data
for i, layer in enumerate(model):
if isinstance(layer, nn.Linear):
layer.weight = nn.Parameter(weights[i])
layer.biases = nn.Parameter(biases[i])
target_output = tensor(eval('[np.float64(' + outputs.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64) (edited)output = open("model (1).txt").read()
outputs = open("outputs (2).txt").read()
data = output.split("layer")
import torch
import numpy as np
def rm_empty(l):
if '' in l:
l.remove('')
return l
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(int(x.item()))
except:
data += "\x00"
return data
data = rm_empty(data)
from torch import tensor
def parse_data(d):
dn = rm_empty(d.split("\n"))
lr = dn[0]
d2 = ("\n".join(dn[1:])).split("weights")
d2 = rm_empty(d2)
biases = d2[0]
biases = rm_empty(biases.split("\n"))[1:][0]
biases = eval('[np.float64(' + biases.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]')
weights = rm_empty(d2[1].split("\n"))
for i in range(len(weights)):
weights[i] = eval('[np.float64(' + weights[i].replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]')
return lr, biases, weights # in my impl this is tensor(weights, dtype=torch.float64 but i think you need to do math on weights so
weights = []
biases = []
for x in range(len(data)):
_, lrbiases, lrweights = parse_data(data[x])
weights.append(lrweights)
biases.append(lrbiases) (edited)tensor(<varname>, dtype=tensor.float64)output = open("model (1).txt").read()
outputs = open("outputs (2).txt").read()
data = output.split("layer")
import torch
import numpy as np
def rm_empty(l):
if '' in l:
l.remove('')
return l
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(int(x.item()))
except:
data += "\x00"
return data
data = rm_empty(data)
from torch import tensor
def parse_data(d):
dn = rm_empty(d.split("\n"))
lr = dn[0]
d2 = ("\n".join(dn[1:])).split("weights")
d2 = rm_empty(d2)
biases = d2[0]
biases = rm_empty(biases.split("\n"))[1:][0]
biases = tensor(eval('[np.float64(' + biases.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64)
weights = rm_empty(d2[1].split("\n"))
for i in range(len(weights)):
weights[i] = eval('[np.float64(' + weights[i].replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]')
return lr, biases, tensor(weights, dtype=torch.float64)
weights = []
biases = []
for x in range(len(data)):
_, lrbiases, lrweights = parse_data(data[x])
weights.append(lrweights)
biases.append(lrbiases)
from torch import nn
model = nn.Sequential(
nn.Linear(22, 69),
nn.Linear(69, 420),
nn.Linear(420, 800),
nn.Linear(800, 85),
nn.Linear(85, 13),
nn.Linear(13, 37)
)
def tensor_to_ascii(t):
data = ""
for x in t:
try:
data += chr(round(x.item()))
except:
data += "\x00"
return data
for i, layer in enumerate(model):
if isinstance(layer, nn.Linear):
layer.weight = nn.Parameter(weights[i])
layer.biases = nn.Parameter(biases[i])
target_output = tensor(eval('[np.float64(' + outputs.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64) (edited)target_output = tensor(eval('[np.float64(' + outputs.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64)target_output = tensor(eval('[np.float64(' + outputs.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]'), dtype=torch.float64) target_output = eval('[np.float64(' + outputs.replace(" ", '), np.float64(').replace('/', ')/np.float64(') + ')]')from fractions import FractionFraction(8518196211434573697728037, 100000000000000000)[85181962.11434537 -82558593.57841527 51320422.15698447 50855552.596899845
102777290.7469408 260244431.67128614 -41910940.30700645
-121562941.17643394 89706297.60350907 99330170.65949443
-36853890.38421978 95177796.51577635 13157343.127865441 122638034.2406461
75223895.80595507 203024016.244885 212145165.20600376 44208997.46421799
58609160.887382485 328611319.2197367 -111984167.25720419
-4469690.991234731 -70135524.92187999 45010210.01148323 30623208.66198535
2558449.492180466 193122704.82683364 203119671.1013074 11450046.25626932
-1756080.7466687919 -318635976.1328053 156107263.70621404
218812721.0969335 -42383267.35600404 -76017188.644868 15657464.098871475
93862598.79557651]
[ 8.51819621e+07 -8.25585936e+07 5.13204222e+07 5.08555526e+07
1.02777291e+08 2.60244432e+08 -4.19109403e+07 -1.21562941e+08
8.97062976e+07 9.93301707e+07 -3.68538904e+07 9.51777965e+07
1.31573431e+07 1.22638034e+08 7.52238958e+07 2.03024016e+08
2.12145165e+08 4.42089975e+07 5.86091609e+07 3.28611319e+08
-1.11984167e+08 -4.46969099e+06 -7.01355249e+07 4.50102100e+07
3.06232087e+07 2.55844949e+06 1.93122705e+08 2.03119671e+08
1.14500463e+07 -1.75608075e+06 -3.18635976e+08 1.56107264e+08
2.18812721e+08 -4.23832674e+07 -7.60171886e+07 1.56574641e+07
9.38625988e+07][-0.3302665578795254 4.088524661835484 1.582225422025971 2.228352830448657
-8.8105937753601 5.844176881744154 -0.6570651370145247 1.3964525161914585
-0.847161076540201 0.6887171027769219 -0.2769034719969953
3.527297226608247 3.5380032762048694 -0.539706423418792
-0.01838310162286505 -4.152757900644751 6.763915750017028
-1.913941071752785 3.226053300276378 1.0636395444207503 6.77621334041599
1.3337224681807407]W6(W5(W4(W3(W2(W1x+b1)+b2)+b3)+b4+b5)+b6=output
just expand it, get it to Ax=b then solveW6(W5(W4(W3(W2(W1x+b1)+b2)+b3)+b4+b5)+b6=output
just expand it, get it to Ax=b then solve W6W5W4W3W2W1x+W6W5W4W3W2b1+W6W5W4W3b2+W6W5W4b3+W6W5b4+W6b5+b6=outputx = W1^-1 * (W2^-1 * (W3^-1 * (W4^-1 * (W5^-1 * (W6^-1 * output - b6) - b5) - b4) - b3) - b2) - b1 (edited)W6W5W4W3W2W1x+W6W5W4W3W2b1+W6W5W4W3b2+W6W5W4b3+W6W5b4+W6b5+b6=output sympy.matrices.common.NonInvertibleMatrixError: Matrix det == 0; not invertible.sympy.matrices.common.NonInvertibleMatrixError: Matrix det == 0; not invertible. Computes the vector x that approximately solves the equation @sahuang you can compute exact though[[ 50.42092424]
[101.03269245]
[ 26.71849702]
[-36.88773564]
[-76.61594413]
[ 44.39960158]
[ 68.71135152]
[ 36.33306337]
[ 4.41593796]
[119.26109294]
[ 58.48153408]
[ 85.9846144 ]
[ 41.13197924]
[ 27.54137431]
[ 32.35543824]
[ 8.57326218]
[ 22.02081603]
[-24.8457248 ]
[ 77.91928158]
[ 68.94507925]
[ 97.63596957]
[ 47.37988401]][[ 50.42092424]
[101.03269245]
[ 26.71849702]
[-36.88773564]
[-76.61594413]
[ 44.39960158]
[ 68.71135152]
[ 36.33306337]
[ 4.41593796]
[119.26109294]
[ 58.48153408]
[ 85.9846144 ]
[ 41.13197924]
[ 27.54137431]
[ 32.35543824]
[ 8.57326218]
[ 22.02081603]
[-24.8457248 ]
[ 77.91928158]
[ 68.94507925]
[ 97.63596957]
[ 47.37988401]] [[ 50.42092424]
[101.03269245]
[ 26.71849702]
[-36.88773564]
[-76.61594413]
[ 44.39960158]
[ 68.71135152]
[ 36.33306337]
[ 4.41593796]
[119.26109294]
[ 58.48153408]
[ 85.9846144 ]
[ 41.13197924]
[ 27.54137431]
[ 32.35543824]
[ 8.57326218]
[ 22.02081603]
[-24.8457248 ]
[ 77.91928158]
[ 68.94507925]
[ 97.63596957]
[ 47.37988401]] [50.42092424295905, 101.03269245149805, 26.718497020353276, -36.88773564060233, -76.61594412934443, 44.399601584157125, 68.71135152203541, 36.33306337098819, 4.415937955611899, 119.26109293913278, 58.48153408208583, 85.98461439875094, 41.131979235095756, 27.541374306218714, 32.35543824022369, 8.573262176253603, 22.02081603251875, -24.84572479902885, 77.91928157533383, 68.94507925073925, 97.63596957157239, 47.37988400755675]>>> MSE(model(a), target_output) tensor(1.5647e+11, dtype=torch.float64, grad_fn=<MseLossBackward0>)
>>> better but also not close to generated output (edited)model(a) and the output, more == bad) (edited)[85, 77, 68, 67, 84, 70, 123, 110.35490848362011, 44.6688619549253, 113.98153306961444, 99.87441631578926, 67.80495409892433, 81.95437158738532, 104.56908932418375, 59.03581478285347, 40.20940259534488, 87.95837372483226, 35.07210921419155, 104.13904639866911, 120.39146783442436, 32.00000012927558, 125]
how off is this?test_flag = "UMDCTF{test_flag_!!??}"
assert len(test_flag) == 22
# W6(W5(W4(W3(W2(W1x+b1)+b2)+b3)+b4)+b5)+b6=output
x = []
for i in range(len(test_flag)):
x.append([Fraction(ord(test_flag[i]), 1)])
tmp = matmul(weights[0], x)
tmp = matsum(tmp, biases[0])
tmp = matmul(weights[1], tmp)
tmp = matsum(tmp, biases[1])
tmp = matmul(weights[2], tmp)
tmp = matsum(tmp, biases[2])
tmp = matmul(weights[3], tmp)
tmp = matsum(tmp, biases[3])
tmp = matmul(weights[4], tmp)
tmp = matsum(tmp, biases[4])
tmp = matmul(weights[5], tmp)
tmp = matsum(tmp, biases[5])
ys = tmp
basically added this block before calculatingleft = ...
right = ...
# get lcm of all denominators
from math import gcd
from functools import reduce
def lcm(a, b):
return a * b // gcd(a, b)
res = 1
for i in left:
for j in i:
res = lcm(res, j.denominator)
for i in right:
for j in i:
res = lcm(res, j.denominator)
print(res) # lcm
# multiply all fractions by lcm to make int
A = []
for i in left:
A.append([j.numerator * res // j.denominator for j in i])
b = []
for i in right:
b.append(i[0].numerator * res // i[0].denominator)
print(A)
print(b)
# solve A * x = b, x is 8bit int
from z3 import *
x = [BitVec("x%d" % i, 8) for i in range(22)]
s = Solver()
for i in range(22):
s.add(x[i] > 32)
s.add(x[i] < 126)
# start with UMDCTF{ and end with }
s.add(x[0] == ord("U"))
s.add(x[1] == ord("M"))
s.add(x[2] == ord("D"))
s.add(x[3] == ord("C"))
s.add(x[4] == ord("T"))
s.add(x[5] == ord("F"))
s.add(x[6] == ord("{"))
s.add(x[21] == ord("}"))
# solve the system of equations
for i in range(22):
s.add(sum([A[i][j] * x[j] for j in range(22)]) - b[i] == 0)
while s.check() == sat:
m = s.model()
print("".join([chr(int(eval(m[x[i]].as_string()))) for i in range(22)]))
s.add(Or([x[i] != m[x[i]] for i in range(22)]))from z3 import *
layers = [[[], []]]
data = open("./model.txt", "r").readlines()
biases = False
for l in data:
l = l.strip()
if "layer" in l:
i = int(l[-1])
layers.append([[], []])
elif "biases" in l:
biases = True
elif "weights" in l:
biases = False
elif len(l) > 0:
nums = [RealVal(x) for x in l.split(" ")]
if biases:
layers[i][1] += nums
else:
layers[i][0] += nums
layer_data = [[]]
for i in range(22): # input layer size
layer_data[0].append(Int(str(i)))
for i in range(1, len(layers)):
layer_data.append([])
for j in range(len(layers[i][1])):
n = RealVal(0)
for k in range(len(layer_data[i - 1])):
n += layer_data[i - 1][k] * layers[i][0][j * len(layer_data[i - 1]) + k]
n += layers[i][1][j]
layer_data[-1].append(n)
outputs = [RealVal(x) for x in open("./outputs.txt").read().strip().split(" ")]
s = Solver()
for i in range(len(layer_data[-1])):
s.add(layer_data[-1][i] == outputs[i])
for i in layer_data[0]:
s.add(i > RealVal(32))
s.add(i < RealVal(128))
flag_header = [85,77,68,67,84,70,123] # UMDCTF{
for i in range(len(flag_header)):
s.add(layer_data[0][i] == RealVal(flag_header[i]))
s.check()
print(s.model())